feat(plugins): add document format registration ABI#941
Open
mimeding wants to merge 1 commit into
Open
Conversation
This was referenced Apr 24, 2026
89c5ddf to
73a299c
Compare
73a299c to
575de84
Compare
3d87e66 to
00343dc
Compare
1e7a778 to
75bca63
Compare
Adds the host-side bridge between the plugin ABI and the document format registry so plugin-provided parsers and emitters plug into DocumentFormatRegistry the same way the in-tree adapters do. A plugin that registers a parser through this surface ends up as a regular adapter consumers can look up via registry.adapter(for:) — no plugin- specific branch in the consumer. The plugin-side invocation (how a plugin's invoke pointer gets wired back into the shim adapter) is structured around a PluginDocumentInvoker protocol so the host-to-plugin callback is a single seam. This PR wires the Swift side end-to-end and tests it with a fake invoker; the PluginManager plumbing that threads each plugin's real invoke pointer into PluginDocumentInvoker lands with a follow-up since it needs access to PluginManager internals. - osaurus_plugin.h: adds osr_register_parser_fn / register_emitter_fn / unregister_format_fn signatures and the trailing struct fields, with full request/response JSON contract documented inline. Trailing fields — older plugins compiled against the v2 layout pre-this-PR keep loading because the host allocates the struct and zero-inits the new tail. - PluginBackedDocumentAdapter.swift: Swift shims implementing DocumentFormatAdapter and DocumentFormatEmitter by forwarding to a plugin via PluginDocumentInvoker.invoke(type:id:payload:). Surfaces only the textFallback representation today; richer representations (Workbook, PDFDocumentRepresentation) come with a response-schema extension once a first plugin needs them. - PluginDocumentRegistry.swift: owns format_id -> plugin_id ownership so one plugin can't unregister another's format (or overwrite an in-tree built-in). Returns JSON envelopes matching the C-header contract. - Tests: 8 scenarios covering happy-path registration, adapter → plugin invocation threading, plugin error propagation, emitter routing, another-plugin-cannot-overwrite, reject-unregister-by- other, unregisterAll teardown on plugin unload, and malformed-JSON rejection.
75bca63 to
fd6a6e0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This re-issues PR #941 as a focused one-commit branch on current
origin/main(9e5c8bf0). The old stacked document/PPTX context has been dropped; this PR is only the plugin document-format registration surface.What changed
register_parser,register_emitter, andunregister_format.PluginDocumentRegistry.DocumentFormatAdapter/DocumentFormatEmittershims that invoke the loaded plugin route handler.Validation
swift test --package-path Packages/OsaurusCore --filter 'PluginDocumentRegistry|PluginHostAPI|PluginHostAPIStructLayout|PluginHostFreeString|PluginCompleteCancel'passed, 86 tests.git diff --check origin/main...HEADpassed.swiftlint lint --strict --config .swiftlint.ymlpassed on the two new plugin document shim files.PluginManager.swift,ExternalPlugin.swift,PluginHostAPI.swift); those violations are outside the added hunks.Non-scope